/*
 *  Copyright (C) 2011 JiangHongTiao <jjurco.sk_gmail.com>
 * 
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 * 
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 * 
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
package sk.lieskove.jianghongtiao.common.utils;

import org.apache.log4j.Logger;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
import sk.lieskove.jianghongtiao.common.utils.xml.ProcessXML;

import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.XPathExpressionException;
import java.io.IOException;
import java.util.*;


/**
 * http://www.webmaster-toolkit.com/mime-types.shtml
 * http://mindprod.com/jgloss/mime.html
 * @author xjuraj
 */
public final class MimeUtils {

    private static CharSequence CONTENT_TYPE_SEPARATOR = ";";
    private static final Set<String> mimeTypes = new TreeSet<String>();
    private Logger log = Logger.getLogger(MimeUtils.class.getName());

    public MimeUtils() {
        fillMimeTypes();
    }

    /**
     * extract mime type from string returned by server. This string sometimes
     * contains also encoding. When value is null, result is also null
     * 
     * @param contentType content type string returned by server
     * @return Mime type extracted from @contentType
     */
    public static String getMimeTypeFromRemoteContentType(String contentType) {
        if(contentType == null){
            return null;
        }
        String result = contentType.trim();
        if (contentType.contains(CONTENT_TYPE_SEPARATOR)) {
            result = contentType.substring(0, contentType.indexOf(CONTENT_TYPE_SEPARATOR.charAt(0)));
        }
        return result;
    }


    /**
     * get all mime types starting with some string
     * @param startWith prefix of mime type string
     * @return list of all mime types starting with this string
     */
    public List<String> getAllStartingWith(String startWith) {
        List<String> result = new ArrayList<String>();
        for (Iterator<String> it = mimeTypes.iterator(); it.hasNext();) {
            String string = it.next();
            if (string.startsWith(startWith)) {
                result.add(string);
            }
        }
        return result;
    }

    /**
     * add all known (for me) mime types
     */
    private void fillMimeTypes() {
        try {
            Document openDocument = ProcessXML.openDocument("resources/mime-types-with-ext.xml");
            NodeList nodeList = ProcessXML.getNodeListByXPathQuery(
                    "//mime-mapping/mime-type", openDocument);
            for (int i = 0; i < nodeList.getLength(); i++) {
                Node item = nodeList.item(i);
                mimeTypes.add(item.getTextContent());
            }
        } catch (XPathExpressionException ex) {
            log.error("XPath expression is not correct.", ex);
        } catch (SAXException ex) {
            log.error("SAX parsing exception.", ex);
        } catch (ParserConfigurationException ex) {
            log.error("Parser configuration is not correct.", ex);
        } catch (IOException ex) {
            log.error("Reading file exception.", ex);
        }
    }
}
